package abel.wlmr.model.unit;

import java.nio.charset.Charset;

import abel.util.StdBcdNumber;
import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import io.netty.buffer.ByteBuf;

/**
 * 数据内容 数据格式 字节数
 * 厂商代号 ASCII 4
 * 设备编号 ASCII 8
 * 终端软件版本号 ASCII 4
 * 终端软件发布日期：日月年 见附录 C.20 3
 * 终端配置容量信息码 ASCII 11
 * 终端通信协议.版本号 ASCII 4
 * 终端硬件版本号 ASCII 4
 * 终端硬件发布日期：日月年 见附录 C.20 3
 * 
 * @author Abel
 *
 */
public class Afn09F1UpUnit extends WlmrBaseUnit {

    private static final short FIXED_LENGTH = 4 + 8 + 4 + 3 + 11 + 4 + 4 + 3;

    private String manufacturer;

    private String machineNo;

    private String softVersion;

    private StdBcdNumber softReleaseDate;

    private String termCapacity;

    private String protocolVersion;

    private String hardVersion;

    private StdBcdNumber hardReleaseDate;

    public Afn09F1UpUnit() {
        super();
    }

    public Afn09F1UpUnit(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitPart#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (manufacturer == null || manufacturer.getBytes().length != 4
            || manufacturer.getBytes().length != manufacturer.length()) {
            throw new IllegalArgumentException("manufacturer should be of 4 ascii long.");
        }
        if (machineNo == null || machineNo.getBytes().length != 8
            || machineNo.getBytes().length != machineNo.length()) {
            throw new IllegalArgumentException("machineNo should be of 8 ascii long.");
        }
        if (softVersion == null || softVersion.getBytes().length != 4
            || softVersion.getBytes().length != softVersion.length()) {
            throw new IllegalArgumentException("softVersion should be of 4 ascii long.");
        }
        if (softReleaseDate == null || softReleaseDate.length() != 3) {
            throw new IllegalArgumentException("soft release date should be 3 digits long");
        }

        if (termCapacity == null || termCapacity.getBytes().length != 11
            || termCapacity.getBytes().length != termCapacity.length()) {
            throw new IllegalArgumentException("termCapacity should be of 11 ascii long.");
        }
        if (protocolVersion == null || protocolVersion.getBytes().length != 4
            || protocolVersion.getBytes().length != protocolVersion.length()) {
            throw new IllegalArgumentException("protocolVersion should be of 4 ascii long.");
        }
        if (hardVersion == null || hardVersion.getBytes().length != 4
            || hardVersion.getBytes().length != hardVersion.length()) {
            throw new IllegalArgumentException("hardVersion should be of 4 ascii long.");
        }
        if (hardReleaseDate == null || hardReleaseDate.length() != 3) {
            throw new IllegalArgumentException("hard release date should be 3 digits long");
        }

        buf.writeBytes(manufacturer.getBytes());
        buf.writeBytes(machineNo.getBytes());
        buf.writeBytes(softVersion.getBytes());
        buf.writeBytes(softReleaseDate.toBytes());

        buf.writeBytes(termCapacity.getBytes());
        buf.writeBytes(protocolVersion.getBytes());
        buf.writeBytes(hardVersion.getBytes());
        buf.writeBytes(hardReleaseDate.toBytes());

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitPart#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        manufacturer = buf.readCharSequence(4, Charset.defaultCharset()).toString();
        machineNo = buf.readCharSequence(8, Charset.defaultCharset()).toString();
        softVersion = buf.readCharSequence(4, Charset.defaultCharset()).toString();

        softReleaseDate = new StdBcdNumber();
        softReleaseDate.populateBytes(buf, 3);
        try {
            softReleaseDate.toMeterC20Joda();
        } catch (IllegalArgumentException e) {
            throw new WlmrException("fail to parse C20 joda caused by " + e.getMessage(), e);
        }

        termCapacity = buf.readCharSequence(11, Charset.defaultCharset()).toString();
        protocolVersion = buf.readCharSequence(4, Charset.defaultCharset()).toString();
        hardVersion = buf.readCharSequence(4, Charset.defaultCharset()).toString();

        hardReleaseDate = new StdBcdNumber();
        hardReleaseDate.populateBytes(buf, 3);
        try {
            hardReleaseDate.toMeterC20Joda();
        } catch (IllegalArgumentException e) {
            throw new WlmrException("fail to parse C20 joda caused by " + e.getMessage(), e);
        }

        return getGuessedLength();
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format(
            "{manufacturer:%s, machineNo:%s, softVersion:%s, softReleaseDate:%s, termCapacity:%s, protocolVersion:%s, hardVersion:%s, hardReleaseDate:%s}",
            manufacturer, machineNo, softVersion, softReleaseDate, termCapacity, protocolVersion, hardVersion,
            hardReleaseDate);
    }

    /**
     * 厂商代号 ASCII 4
     * 
     * @return the manufacturer
     */
    public String getManufacturer() {
        return manufacturer;
    }

    /**
     * 厂商代号 ASCII 4
     * 
     * @param manufacturer
     *            the manufacturer to set
     */
    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    /**
     * 设备编号 ASCII 8
     * 
     * @return the machineNo
     */
    public String getMachineNo() {
        return machineNo;
    }

    /**
     * 设备编号 ASCII 8
     * 
     * @param machineNo
     *            the machineNo to set
     */
    public void setMachineNo(String machineNo) {
        this.machineNo = machineNo;
    }

    /**
     * 终端软件版本号 ASCII 4
     * 
     * @return the softVersion
     */
    public String getSoftVersion() {
        return softVersion;
    }

    /**
     * 终端软件版本号 ASCII 4
     * 
     * @param softVersion
     *            the softVersion to set
     */
    public void setSoftVersion(String softVersion) {
        this.softVersion = softVersion;
    }

    /**
     * 终端软件发布日期：日月年 见附录 C.20 3
     * 
     * @return the softReleaseDate
     */
    public StdBcdNumber getSoftReleaseDate() {
        return softReleaseDate;
    }

    /**
     * 终端软件发布日期：日月年 见附录 C.20 3
     * 
     * @param softReleaseDate
     *            the softReleaseDate to set
     */
    public void setSoftReleaseDate(StdBcdNumber softReleaseDate) {
        this.softReleaseDate = softReleaseDate;
    }

    /**
     * 终端配置容量信息码 ASCII 11
     * 
     * @return the termCapacity
     */
    public String getTermCapacity() {
        return termCapacity;
    }

    /**
     * 终端配置容量信息码 ASCII 11
     * 
     * @param termCapacity
     *            the termCapacity to set
     */
    public void setTermCapacity(String termCapacity) {
        this.termCapacity = termCapacity;
    }

    /**
     * 终端通信协议.版本号 ASCII 4
     * 
     * @return the protocolVersion
     */
    public String getProtocolVersion() {
        return protocolVersion;
    }

    /**
     * 终端通信协议.版本号 ASCII 4
     * 
     * @param protocolVersion
     *            the protocolVersion to set
     */
    public void setProtocolVersion(String protocolVersion) {
        this.protocolVersion = protocolVersion;
    }

    /**
     * 终端硬件版本号 ASCII 4
     * 
     * @return the hardVersion
     */
    public String getHardVersion() {
        return hardVersion;
    }

    /**
     * 终端硬件版本号 ASCII 4
     * 
     * @param hardVersion
     *            the hardVersion to set
     */
    public void setHardVersion(String hardVersion) {
        this.hardVersion = hardVersion;
    }

    /**
     * 终端硬件发布日期：日月年 见附录 C.20 3
     * 
     * @return the hardReleaseDate
     */
    public StdBcdNumber getHardReleaseDate() {
        return hardReleaseDate;
    }

    /**
     * 终端硬件发布日期：日月年 见附录 C.20 3
     * 
     * @param hardReleaseDate
     *            the hardReleaseDate to set
     */
    public void setHardReleaseDate(StdBcdNumber hardReleaseDate) {
        this.hardReleaseDate = hardReleaseDate;
    }

}
